home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / VIEWERS / MSDOS / GIFLIB12.ZIP / UTIL / GIFASM.C < prev    next >
C/C++ Source or Header  |  1991-05-12  |  11KB  |  315 lines

  1. /*****************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Jul. 1989   *
  5. ******************************************************************************
  6. * Program to assemble/disassemble GIF files: disassembles multi image file   *
  7. * into seperated files, or assembles few single image GIF files into one.    *
  8. * Options:                                     *
  9. * -q : quite printing mode.                             *
  10. * -a : assemble few files into one (default)                     *
  11. * -d name : disassmble given GIF file into seperate files derived from name. *
  12. * -h : on line help.                                 *
  13. ******************************************************************************
  14. * History:                                     *
  15. * 7 Jul 89 - Version 1.0 by Gershon Elber.                     *
  16. *****************************************************************************/
  17.  
  18. #ifdef __MSDOS__
  19. #include <stdlib.h>
  20. #include <alloc.h>
  21. #endif /* __MSDOS__ */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include "gif_lib.h"
  27. #include "getarg.h"
  28.  
  29. #define PROGRAM_NAME    "GifAsm"
  30.  
  31. #ifdef __MSDOS__
  32. extern unsigned int
  33.     _stklen = 16384;                 /* Increase default stack size. */
  34. #endif /* __MSDOS__ */
  35.  
  36. #ifdef SYSV
  37. static char *VersionStr =
  38.         "Gif library module,\t\tGershon Elber\n\
  39.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  40. static char
  41.     *CtrlStr = "GifAsm q%- a%- d%-OutFileName!s h%- GifFile(s)!*s";
  42. #else
  43. static char
  44.     *VersionStr =
  45.     PROGRAM_NAME
  46.     GIF_LIB_VERSION
  47.     "    Gershon Elber,    "
  48.     __DATE__ ",   " __TIME__ "\n"
  49.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  50. static char
  51.     *CtrlStr =
  52.     PROGRAM_NAME
  53.     " q%- a%- d%-OutFileName!s h%- GifFile(s)!*s";
  54. #endif /* SYSV */
  55.  
  56. static int
  57.     AsmFlag = FALSE;
  58.  
  59. static void DoAssembly(int NumFiles, char **FileNames);
  60. static void DoDisassembly(char *InFileName, char *OutFileName);
  61. static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut);
  62.  
  63. /******************************************************************************
  64. * Interpret the command line and scan the given GIF file.              *
  65. ******************************************************************************/
  66. void main(int argc, char **argv)
  67. {
  68.     int    Error, NumFiles, DisasmFlag = FALSE, HelpFlag = FALSE;
  69.     char **FileNames = NULL, *OutFileName;
  70.  
  71.     if ((Error = GAGetArgs(argc, argv, CtrlStr,
  72.         &GifQuitePrint, &AsmFlag, &DisasmFlag, &OutFileName,
  73.         &HelpFlag, &NumFiles, &FileNames)) != FALSE) {
  74.     GAPrintErrMsg(Error);
  75.     GAPrintHowTo(CtrlStr);
  76.     exit(1);
  77.     }
  78.  
  79.     if (HelpFlag) {
  80.     fprintf(stderr, VersionStr);
  81.     GAPrintHowTo(CtrlStr);
  82.     exit(0);
  83.     }
  84.  
  85.     if (!AsmFlag && !DisasmFlag) AsmFlag = TRUE; /* Make default - assemble. */
  86.     if (AsmFlag && NumFiles < 2) {
  87.     GIF_MESSAGE("At list two GIF files are required to assembly operation.");
  88.     GAPrintHowTo(CtrlStr);
  89.     exit(1);
  90.     }
  91.     if (!AsmFlag && NumFiles > 1) {
  92.     GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  93.     GAPrintHowTo(CtrlStr);
  94.     exit(1);
  95.     }
  96.  
  97.     if (AsmFlag)
  98.         DoAssembly(NumFiles, FileNames);
  99.     else
  100.     DoDisassembly(NumFiles == 1 ? *FileNames : NULL, OutFileName);
  101. }
  102.  
  103. /******************************************************************************
  104. * Perform the assembly operation - take few input files into one output.      *
  105. ******************************************************************************/
  106. static void DoAssembly(int NumFiles, char **FileNames)
  107. {
  108.     int    i, ExtCode, CodeSize;
  109.     GifRecordType RecordType;
  110.     GifByteType *Extension, *CodeBlock;
  111.     GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
  112.  
  113.     /* Open stdout for the output file: */
  114.     if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
  115.     QuitGifError(GifFileIn, GifFileOut);
  116.  
  117.     /* Scan the content of the GIF file and load the image(s) in: */
  118.     for (i = 0; i < NumFiles; i++) {
  119.     if ((GifFileIn = DGifOpenFileName(FileNames[i])) == NULL)
  120.         QuitGifError(GifFileIn, GifFileOut);
  121.  
  122.     /* And dump out screen descriptor iff its first image.    */
  123.     if (i == 0)
  124.         if (EGifPutScreenDesc(GifFileOut,
  125.         GifFileIn -> SWidth, GifFileIn -> SHeight,
  126.         GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
  127.         GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR)
  128.         QuitGifError(GifFileIn, GifFileOut);
  129.  
  130.     do {
  131.         if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
  132.         QuitGifError(GifFileIn, GifFileOut);
  133.  
  134.         switch (RecordType) {
  135.         case IMAGE_DESC_RECORD_TYPE:
  136.             if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
  137.             QuitGifError(GifFileIn, GifFileOut);
  138.             /* Put image descriptor to out file: */
  139.             if (EGifPutImageDesc(GifFileOut,
  140.             GifFileIn -> ILeft, GifFileIn -> ITop,
  141.             GifFileIn -> IWidth, GifFileIn -> IHeight,
  142.             GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
  143.             GifFileIn -> IColorMap) == GIF_ERROR)
  144.             QuitGifError(GifFileIn, GifFileOut);
  145.  
  146.             /* Now read image itself in decoded form as we dont      */
  147.             /* dont care what is there, and this is much faster.     */
  148.             if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
  149.              || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
  150.             QuitGifError(GifFileIn, GifFileOut);
  151.             while (CodeBlock != NULL)
  152.             if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
  153.                 EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
  154.                 QuitGifError(GifFileIn, GifFileOut);
  155.             break;
  156.         case EXTENSION_RECORD_TYPE:
  157.             /* Skip any extension blocks in file: */
  158.             if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
  159.             == GIF_ERROR)
  160.             QuitGifError(GifFileIn, GifFileOut);
  161.             if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
  162.                                Extension) == GIF_ERROR)
  163.             QuitGifError(GifFileIn, GifFileOut);
  164.  
  165.             /* No support to more than one extension blocks, discard.*/
  166.             while (Extension != NULL)
  167.             if (DGifGetExtensionNext(GifFileIn, &Extension)
  168.                 == GIF_ERROR)
  169.                 QuitGifError(GifFileIn, GifFileOut);
  170.             break;
  171.         case TERMINATE_RECORD_TYPE:
  172.             break;
  173.         default:        /* Should be traps by DGifGetRecordType. */
  174.             break;
  175.         }
  176.     }
  177.     while (RecordType != TERMINATE_RECORD_TYPE);
  178.  
  179.     if (DGifCloseFile(GifFileIn) == GIF_ERROR)
  180.         QuitGifError(GifFileIn, GifFileOut);
  181.     }
  182.  
  183.     if (EGifCloseFile(GifFileOut) == GIF_ERROR)
  184.     QuitGifError(GifFileIn, GifFileOut);
  185. }
  186.  
  187. /******************************************************************************
  188. * Perform the disassembly operation - take one input files into few output.   *
  189. ******************************************************************************/
  190. static void DoDisassembly(char *InFileName, char *OutFileName)
  191. {
  192.     int    i, ExtCode, CodeSize, FileNum = 0, FileEmpty;
  193.     GifRecordType RecordType;
  194.     char CrntFileName[80], *p;
  195.     GifByteType *Extension, *CodeBlock;
  196.     GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
  197.  
  198.     /* If name has type postfix, strip it out, and make sure name is less    */
  199.     /* or equal to 6 chars, so we will have 2 chars in name for numbers.     */
  200.     for (i = 0; i < strlen(OutFileName);  i++)/* Make sure all is upper case.*/
  201.     if (islower(OutFileName[i]))
  202.         OutFileName[i] = toupper(OutFileName[i]);
  203.  
  204.     if ((p = strrchr(OutFileName, '.')) != NULL && strlen(p) <= 4) p[0] = 0;
  205.     if ((p = strrchr(OutFileName, '/')) != NULL ||
  206.     (p = strrchr(OutFileName, '\\')) != NULL ||
  207.     (p = strrchr(OutFileName, ':')) != NULL) {
  208.     if (strlen(p) > 7) p[7] = 0;  /* p includes the '/', '\\', ':' char. */
  209.     }
  210.     else {
  211.     /* Only name is given for current directory: */
  212.     if (strlen(OutFileName) > 6) OutFileName[6] = 0;
  213.     }
  214.  
  215.     /* Open input file: */
  216.     if (InFileName != NULL) {
  217.     if ((GifFileIn = DGifOpenFileName(InFileName)) == NULL)
  218.         QuitGifError(GifFileIn, GifFileOut);
  219.     }
  220.     else {
  221.     /* Use the stdin instead: */
  222.     if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
  223.         QuitGifError(GifFileIn, GifFileOut);
  224.     }
  225.  
  226.     /* Scan the content of GIF file and dump image(s) to seperate file(s): */
  227.     do {
  228.     sprintf(CrntFileName, "%s%02d.gif", OutFileName, FileNum++);
  229.     if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE)) == NULL)
  230.         QuitGifError(GifFileIn, GifFileOut);
  231.     FileEmpty = TRUE;
  232.  
  233.     /* And dump out its exactly same screen information: */
  234.     if (EGifPutScreenDesc(GifFileOut,
  235.         GifFileIn -> SWidth, GifFileIn -> SHeight,
  236.         GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
  237.         GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR)
  238.         QuitGifError(GifFileIn, GifFileOut);
  239.  
  240.     do {
  241.         if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
  242.         QuitGifError(GifFileIn, GifFileOut);
  243.  
  244.         switch (RecordType) {
  245.         case IMAGE_DESC_RECORD_TYPE:
  246.             FileEmpty = FALSE;
  247.             if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
  248.             QuitGifError(GifFileIn, GifFileOut);
  249.             /* Put same image descriptor to out file: */
  250.             if (EGifPutImageDesc(GifFileOut,
  251.             GifFileIn -> ILeft, GifFileIn -> ITop,
  252.             GifFileIn -> IWidth, GifFileIn -> IHeight,
  253.             GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
  254.             GifFileIn -> IColorMap) == GIF_ERROR)
  255.             QuitGifError(GifFileIn, GifFileOut);
  256.  
  257.             /* Now read image itself in decoded form as we dont      */
  258.             /* really care what is there, and this is much faster.   */
  259.             if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
  260.              || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
  261.             QuitGifError(GifFileIn, GifFileOut);
  262.             while (CodeBlock != NULL)
  263.             if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
  264.                 EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
  265.             QuitGifError(GifFileIn, GifFileOut);
  266.             break;
  267.         case EXTENSION_RECORD_TYPE:
  268.             FileEmpty = FALSE;
  269.             /* Skip any extension blocks in file: */
  270.             if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
  271.             == GIF_ERROR)
  272.             QuitGifError(GifFileIn, GifFileOut);
  273.             if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
  274.                             Extension) == GIF_ERROR)
  275.             QuitGifError(GifFileIn, GifFileOut);
  276.  
  277.             /* No support to more than one extension blocks, discard.*/
  278.             while (Extension != NULL)
  279.             if (DGifGetExtensionNext(GifFileIn, &Extension)
  280.                 == GIF_ERROR)
  281.                 QuitGifError(GifFileIn, GifFileOut);
  282.             break;
  283.         case TERMINATE_RECORD_TYPE:
  284.             break;
  285.         default:        /* Should be traps by DGifGetRecordType. */
  286.             break;
  287.         }
  288.     }
  289.     while (RecordType != IMAGE_DESC_RECORD_TYPE &&
  290.            RecordType != TERMINATE_RECORD_TYPE);
  291.  
  292.     if (EGifCloseFile(GifFileOut) == GIF_ERROR)
  293.         QuitGifError(GifFileIn, GifFileOut);
  294.     if (FileEmpty) {
  295.         /* Might happen on last file - delete it if so: */
  296.         unlink(CrntFileName);
  297.     }
  298.    }
  299.     while (RecordType != TERMINATE_RECORD_TYPE);
  300.  
  301.     if (DGifCloseFile(GifFileIn) == GIF_ERROR)
  302.     QuitGifError(GifFileIn, GifFileOut);
  303. }
  304.  
  305. /******************************************************************************
  306. * Close both input and output file (if open), and exit.                  *
  307. ******************************************************************************/
  308. static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
  309. {
  310.     PrintGifError();
  311.     if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
  312.     if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
  313.     exit(1);
  314. }
  315.